﻿using System;
using System.Collections.Generic;
using System.Windows;

namespace BizControl.Presentation.Infrastructure.Controls.Graph
{
  public class LayoutManager : DependencyObject
  {
    private static LayoutManager _instance;

    public static LayoutManager Instance
    {
      get
      {
        if (_instance == null)
          _instance = new LayoutManager();
        return _instance;
      }
    }

    protected LayoutManager()
    {
    }

    public void ContinueLayout()
    {
      foreach (var layout in graphLayouts)
      {
        layout.ContinueLayout();
      }
    }

    public void Relayout()
    {
      foreach (var layout in graphLayouts)
      {
        layout.Relayout();
      }
    }

    protected readonly HashSet<BCGraphLayout> graphLayouts = new HashSet<BCGraphLayout>();

    public static readonly DependencyProperty ManagedLayoutProperty =
      DependencyProperty.RegisterAttached("ManagedLayout", typeof(bool), typeof(LayoutManager), new PropertyMetadata(false, ManagedLayout_PropertyChanged));

    [AttachedPropertyBrowsableForChildren]
    public static bool GetManagedLayout(DependencyObject obj)
    {
      return (bool)obj.GetValue(ManagedLayoutProperty);
    }

    public static void SetManagedLayout(DependencyObject obj, bool value)
    {
      obj.SetValue(ManagedLayoutProperty, value);
    }

    protected static void ManagedLayout_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
      var graphLayout = obj as BCGraphLayout;
      if (graphLayout == null)
        return;

      if ((bool)e.NewValue)
      {
        //the layout became managed
        Instance.graphLayouts.Add(graphLayout);
        graphLayout.Unloaded += GraphLayout_Unloaded;
      }
      else if ((bool)e.OldValue && (((bool)e.NewValue) == false) && Instance.graphLayouts.Contains(graphLayout))
      {
        //the layout became unmanaged
        Instance.graphLayouts.Remove(graphLayout);
        graphLayout.Unloaded -= GraphLayout_Unloaded;
      }
    }

    private static void GraphLayout_Unloaded(object s, RoutedEventArgs args)
    {
      if (s is BCGraphLayout)
        Instance.graphLayouts.Remove(s as BCGraphLayout);
    }
  }
}
